/*
 * @Author: dark-snow 1306808708@qq.com
 * @Date: 2023-07-07 09:43:17
 * @LastEditors: dark-snow 1306808708@qq.com
 * @LastEditTime: 2023-07-07 14:48:21
 * @FilePath: \wifi_server_030704\components\user_component\user_spi.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "user_spi.h"

#define EEPROM_HOST SPI2_HOST

#define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 7
#define PIN_NUM_CLK 6
#define PIN_NUM_CS 10

static const char TAG[] = "user spi";
spi_device_handle_t spi;

void spi_bus_init(void)
{

	ESP_LOGI(TAG, "Initializing bus SPI%d...", EEPROM_HOST + 1);
	spi_bus_config_t buscfg = {
		.miso_io_num = PIN_NUM_MISO,
		.mosi_io_num = PIN_NUM_MOSI,
		.sclk_io_num = PIN_NUM_CLK,
		.quadwp_io_num = -1,
		.quadhd_io_num = -1,
		.max_transfer_sz = 32,
	};
	// Initialize the SPI bus
	ESP_ERROR_CHECK(spi_bus_initialize(EEPROM_HOST, &buscfg, SPI_DMA_CH_AUTO));

	spi_device_interface_config_t devcfg = {
		.clock_speed_hz = SPI_MASTER_FREQ_10M, // Clock out at 10 MHz,
		.mode = 0,							   // SPI mode 0
		/*
		 * The timing requirements to read the busy signal from the EEPROM cannot be easily emulated
		 * by SPI transactions. We need to control CS pin by SW to check the busy signal manually.
		 */
		.spics_io_num = -1,
		.queue_size = 7, // 传输队列大小，决定了等待传输数据的数量
	};
	ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &devcfg, &spi));

	// cs片选引脚初始化
	// gpio_pad_select_gpio(PIN_NUM_CS);				  // 选择一个GPIO
	gpio_set_direction(PIN_NUM_CS, GPIO_MODE_OUTPUT); // 把这个GPIO作为输出
}

esp_err_t spi_write(spi_device_handle_t spi, uint8_t *data, uint8_t len)
{
	esp_err_t ret;
	spi_transaction_t t;
	if (len == 0)
		return ESP_FAIL;	  // no need to send anything
	memset(&t, 0, sizeof(t)); // Zero out the transaction

	gpio_set_level(PIN_NUM_CS, 0);

	t.length = len * 8;							// Len is in bytes, transaction length is in bits.
	t.tx_buffer = data;							// Data
	t.user = (void *)1;							// D/C needs to be set to 1
	ret = spi_device_polling_transmit(spi, &t); // Transmit!
	assert(ret == ESP_OK);						// Should have had no issues.

	gpio_set_level(PIN_NUM_CS, 1);
	return ret;
}

esp_err_t spi_read(spi_device_handle_t spi, uint8_t *data)
{
	spi_transaction_t t;

	gpio_set_level(PIN_NUM_CS, 0);

	memset(&t, 0, sizeof(t));
	t.length = 8;
	t.flags = SPI_TRANS_USE_RXDATA;
	t.user = (void *)1;
	esp_err_t ret = spi_device_polling_transmit(spi, &t);
	assert(ret == ESP_OK);
	*data = t.rx_data[0];

	gpio_set_level(PIN_NUM_CS, 1);

	return ret;
}